home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The PC-SIG Library 10
/
The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso
/
PC_SIGCD
/
26
/
3
/
DISK2631.ZIP
/
BTRIEV.ZIP
/
BTRIEV.BAS
Wrap
BASIC Source File
|
1990-05-03
|
6KB
|
153 lines
' This SUBprocedure provides the interface between Spectra Publishing's
' PowerBASIC 2.00 compiler and Novell's BTRIEVE file system on PCDOS/MSDOS
' machines.
' In order to use the SUB, include its source code in your program with the
' $INCLUDE metastatement: $INCLUDE "POWERBBT.BAS"
' Each time you wish to perform a BTRIEVE operation, use the CALL statement
' to call the SUB with the following parameters:
' CALL BTRV(OPERATION%, RETSTATUS%, FCBPOSBLOCK$, DATABUFFER$, _
' DATABUFLEN%, KEYBUFFER$, KEYNUMBER%)
' where: OPERATION% is the BTRIEVE operation code for the desired function.
' RETSTATUS% is a BTRIEVE status code returned after the desired
' function is attempted.
' FCBPOSBLOCK$ is a 128-byte data area containing file control block
' (FCB) and position information which must not be changed by
' your program.
' DATABUFFER$ is a data buffer used to specify special information
' such as file specifications, key characteristics, etc. Its
' structure will be defined by your program with a FIELD
' statement.
' DATABUFLEN% is the length of the data buffer, DATABUFFER$.
' KEYBUFFER$ is the key buffer.
' KEYNUMBER% is the key number to be processed.
' Important note: The BTRV routine resets the currently-active PowerBASIC
' data segment to the default data segment (by executing a DEF SEG state-
' ment with no argument). If you set a different segment with DEF SEG in
' your main program and then call BTRV, you will need to execute your DEF
' SEG statement again (after the call), if you wish to continue using your
' segment as PowerBASIC's data segment; otherwise, the default data segment
' will be active when BTRV returns to your main program.
sub BTRV(Operation%, RetStatus%, FCBPosBlock$, DataBuffer$, DataBufLen%, _
KeyBuffer$, KeyNumber%)
static VersionDetermined%, BMULTIPresent%, BMULTIProcessID%
local CriticalErrorVec$ 'holds critical error handler vector
dim ParamBlock%(0:13) 'local array holds 14-word parameter block
%AX = 1 : %BX = 2 : %DX = 4 : %DS = 8 'register equates for use with REG
'parameter positions within ParamBlock% array
%DBOfst = 0 : %DBSeg = 1 : %DBLength = 2 : %PosOfst = 3 : %PosSeg = 4
%FCBOfst = 5 : %FCBSeg = 6 : %OpCode = 7 : %KBOfst = 8 : %KBSeg = 9
%KeyInfo = 10: %StatOfst = 11 : %StatSeg = 12 : %IfaceID = 13
%FCBPosSize = 128 '128 = correct size for FCB + position info
%FCBPosLenErr = 23 'status code returned if size exceeded
%NoBTRIEVEErr = 20 'status code returned if BTRIEVE not loaded
'First, swap critical error handler and check for presence of BTRIEVE
def seg = 0 'use segment zero (DOS INT vectors)
CriticalErrorVec$ = peek$(&h90,4) 'get critical error handler vector
poke$ &h90, peek$(&h51A,4) 'tell DOS to handle errors
'if INT 7B offset = 33 hex, BTRIEVE handler
if peeki(&h7B * 4) = &h33 then ' has been loaded
if VersionDetermined% = 0 then 'DOS version has yet to be determined
incr VersionDetermined% 'set flag since we're determining now
reg %AX, &h3000 'use DOS function 30 hex to get the
call interrupt &h21 ' DOS version number in register AX
if (reg(%AX) AND &h00FF) >= 3 then 'we have DOS 3.00 or above
reg %AX, &hAB00 'so check to see if BMULTI loaded
call interrupt &h2F
if (reg(%AX) AND &h00FF) = 77 then
BMULTIPresent% = 1 'it is loaded, so flag it
else
BMULTIPresent% = 0 'otherwise set flag to zero
end if
end if
end if
else 'BTRIEVE handler isn't loaded, so warn user
RetStatus% = %NoBTRIEVEErr
poke$ &h90, CriticalErrorVec$ 'restore critical error handler
def seg 'and PB default data segment
exit sub 'then quit
end if
if len(FCBPosBlock$) < %FCBPosSize then 'make sure the passed FCBPosBlock$
RetStatus% = %FCBPosLenErr ' is long enough to hold FCB and
' position info -- quit if not
poke$ &h90, CriticalErrorVec$ 'restore critical error handler
def seg 'and PB default data segment
exit sub
end if
'Now set up 14-word parameter block for the BTRIEVE interrupt
ParamBlock%(%DBOfst) = cvi(mkl$(strptr(DataBuffer$))) 'offset and segment
ParamBlock%(%DBSeg) = cvi(mkl$(strseg(DataBuffer$))) 'of data buffer
ParamBlock%(%DBLength) = DataBufLen% 'data buffer length
ParamBlock%(%FCBOfst) = cvi(mkl$(strptr(FCBPosBlock$))) 'offset and segment
ParamBlock%(%FCBSeg) = cvi(mkl$(strseg(FCBPosBlock$))) 'of FCB block
ParamBlock%(%PosOfst) = ParamBlock%(%FCBOfst) + 38 'offset and segment
ParamBlock%(%PosSeg) = ParamBlock%(%FCBSeg) 'of position block
ParamBlock%(%OpCode) = Operation% 'BTRIEVE operation code
ParamBlock%(%KBOfst) = cvi(mkl$(strptr(KeyBuffer$))) 'offset and segment
ParamBlock%(%KBSeg) = cvi(mkl$(strseg(KeyBuffer$))) 'of key buffer
ParamBlock%(%KeyInfo) = len(KeyBuffer$)+(KeyNumber%*256) 'key info word
ParamBlock%(%StatOfst) = cvi(mkl$(varptr(RetStatus%))) 'offset and segment
ParamBlock%(%StatSeg) = cvi(mkl$(varseg(RetStatus%))) 'of status variable
ParamBlock%(%IfaceID) = &h6176 'interface ID
'Now do the interrupt with DS:DX pointing to the parameter block
reg %DX, varptr(ParamBlock%(0))
reg %DS, varseg(ParamBlock%(0))
if BMULTIPresent% = 0 then 'BMULTI not present, so use INT 7B
call interrupt &h7B
else
do 'use BMULTI to do it
if BMULTIProcessID% = 0 then 'get process ID if haven't yet
reg %AX, &hAB01
else
reg %AX, &hAB02 'here if we have process ID -- need
reg %BX, BMULTIProcessID% ' to set it now
end if
call interrupt &h2F 'invoke BMULTI
if (reg(%AX) AND &h00FF) = 0 then exit loop 'go on if done processing
reg %AX, &h0200 'otherwise allow task
call interrupt &h7F ' switch and try request
loop ' again
if BMULTIProcessID% = 0 then BMULTIProcessID% = reg(%BX) 'assign proc ID
end if
DataBufLen% = ParamBlock%(%DBLength) 'pass new data buffer length back
'Now restore critical error handler vector and PB's default data segment
poke$ &h90, CriticalErrorVec$
def seg
end sub